package org.example.server8001.controller;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import org.example.SystemDemo.comment.enity.*;
import org.example.SystemDemo.comment.res.*;
import org.example.SystemDemo.core.Result;
import org.example.SystemDemo.enums.ResultEnum;
import org.example.SystemDemo.comment.req.ConnectREQ;
import org.example.SystemDemo.utils.JSONUtil;
import org.example.server8001.service.InfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.pdf.AcroFields;
import com.itextpdf.text.pdf.BaseFont;
import com.itextpdf.text.pdf.PdfCopy;
import com.itextpdf.text.pdf.PdfImportedPage;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;

@RestController
@RequestMapping("/v1/info")
public class HostController {

    @Autowired
    private InfoService infoService;

    @Autowired
    private ForwardController forward;

    /**
     * 获取客户端列表
     * @return
     */
    @RequestMapping(value = "/getInfo",method = RequestMethod.GET)
    public Result<List<HostInfo>> getInfoList(){
        List<HostInfo> hostInfos = infoService.getBaseMapper().selectList(null);
        return Result.ok(hostInfos);
    }

    /**
     * 建立连接
     */
    @RequestMapping(value = "/connect",method = RequestMethod.POST)
    public Result<?> getConnect(@RequestBody ConnectREQ req) {
        if (!infoService.Connect(req)) {
            return Result.success(ResultEnum.LOGIN_ERROR.getMessage());
        }
        return Result.success(ResultEnum.LOGIN_SUCCESS.getMessage());
    }

    /**
     * 删除连接
     */
    @RequestMapping(value = "/del",method = RequestMethod.POST)
    public Result<?> delConnect(@RequestBody HostInfo req){
        return Result.ok(infoService.removeById(req.getId()));
    }

    /**
     * 导出PDF
     */
    @ResponseBody
    @RequestMapping(value = "/pdf",method = RequestMethod.GET)
    public String createPDF(HttpServletResponse response,@RequestParam("index")Long index) throws DocumentException{
        final PdfViewModel model = new PdfViewModel();

        ClassPathResource resource = new ClassPathResource("template.pdf");

        final HostInfo one = infoService.getOne(Wrappers.<HostInfo>lambdaQuery().eq(HostInfo::getId, index));
        if (Objects.isNull(one)){
            return "index不存在";
        }

        String filename = String.valueOf(index);

        final ClientInfo client = new ClientInfo(null,one.getHostIp(),one.getRunPort());

        final SystemVersionRESP sys = forward.getSysVersionInfo(client).getData();
        final CoreInfoRESP core = forward.getSysCoreInfo(client).getData();
        final List<IpLocationRESP> nio = JSONUtil.parseArray(JSONUtil.stringify(forward.getIpLocationInfo(client).getData()),IpLocationRESP.class);
        final MemoryInfoRESP memory = forward.getMemoryInfo(client).getData();
        final List<DiskInfoRESP> disk = JSONUtil.parseArray(JSONUtil.stringify(forward.getDiskInfo(client).getData()),DiskInfoRESP.class);

        final ArrayList<String> ipList = new ArrayList<>();

        nio.forEach(item -> ipList.add(item.getIpv4Addr()));

        model.setHostname(sys.getHostName());
        model.setOperatingSystem(sys.getOperatingSystemVersion());
        model.setKernel(sys.getBitness());
        model.setIp(String.join(", ",ipList));
        // 系统时间
        model.setTime(core.getClientTime());
        // 系统运行时间
        model.setRuntime(core.getCpuRunTime());
        model.setCpu(sys.getProcessor());
        model.setCpus(core.getCoreNum());
        model.setCpux(String.valueOf(core.getCpuNum()));
        model.setCpun(String.valueOf(core.getPhysicalProcessCount()));

        // 网络信息 网卡排序,只显示经常使用的网卡
        IpLocationRESP max = nio.get(0);
        for (IpLocationRESP item : nio){
            if ((item.getPacketsRecv() + item.getPacketsSent()) > (max.getPacketsRecv() + max.getPacketsSent())){
                max = item;
            }
        }
        model.setSbyte(max.getBytesSent());
        model.setRbyte(max.getBytesRecv());
        model.setNioname(max.getNetName());
        model.setIpaddr(max.getIpv4Addr());
        model.setMac(max.getMacAddr());
        model.setNiomax(max.getNetSpeed());

        // 内存信息
        if (memory.getMemoryChipsInfoRESPList().size() != 0){
            model.setMemoryp(memory.getMemoryChipsInfoRESPList().get(0).getMemoryFrequency());
            model.setNewmemory(memory.getMemoryChipsInfoRESPList().get(0).getMemoryManufacturer());
            model.setMemorytype(memory.getMemoryChipsInfoRESPList().get(0).getMemoryType());
        }else{
            model.setMemoryp("unknown");
            model.setNewmemory("unknown");
            model.setMemorytype("unknown");
        }
        model.setAllmemory(memory.getMemory());
        model.setLomemory(memory.getAvailable());
        model.setUsedmemory(memory.getActualMemory());
        model.setMemoryuseh(memory.getMemoryUsage());

        // 硬盘信息
        final ArrayList<String> diskList = new ArrayList<>();
        disk.get(0).getDiskPartitionInfoRESP().forEach(item -> diskList.add(item.getDiskPartitionMountPoint()));

        model.setDiskname(disk.get(0).getDiskModel());
        model.setDiskpath(disk.get(0).getDiskName());
        model.setDiskper(String.join(", ",diskList));
        model.setDisksize(disk.get(0).getDiskSize());

        // 转换MAP
        Map<String,String> data = new HashMap<>();
        data = JSONUtil.parse(JSONUtil.stringify(model),Map.class);

        // pdf转换
        PdfReader reader;
        OutputStream os = null;
        ByteArrayOutputStream baos = null;
        PdfStamper stamper;


        try {
            os = response.getOutputStream();
            reader = new PdfReader(resource.getInputStream());
            baos = new ByteArrayOutputStream();
            // 根据表单生成一个新的pdf
            stamper = new PdfStamper(reader, baos);
            // 获取pdf表单
            AcroFields formTexts = stamper.getAcroFields();

            // 设置字体(这里设置为系统字体，你也可以引入其他的字体)，不设置很可能，中文无法显示。
            BaseFont bf = BaseFont.createFont();
            formTexts.addSubstitutionFont(bf);

            // 数据查询后，值的植入 强烈推荐键值方式，其他方式很容易混
            Set<String> keySet =  data.keySet();
            for (String key : keySet) {
                formTexts.setField(key, data.get(key).toString());
            }

            stamper.setFormFlattening(true); // 这个必须设
            stamper.close();

            // 创建一个pdf实例
            Document document = new Document();
            PdfCopy copy = new PdfCopy(document, os);
            document.open();
            PdfImportedPage importedPage = copy.getImportedPage(new PdfReader(baos.toByteArray()), 1);
            copy.addPage(importedPage);
            document.close(); // open和close一套

            // 强制下载
            //response.reset();
            response.setContentType("application/pdf");
            response.setHeader("Content-Disposition", "attachment;fileName="
                    + URLEncoder.encode(filename, "UTF-8"));

        } catch (IOException e) {
            e.printStackTrace();
        } finally { // 最后一定要关闭流
            try {
                baos.close();
                os.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

}
